//////////////////////////////////////////////////
// glStore.h
//
// Author: Tarik Belabbas et Adrien Hoffer
//////////////////////////////////////////////////

#ifndef GLSTORE_H_
#define GLSTORE_H_

/**
 * Implementation of a vertex attributes store.
 */
template < typename Type >
class glStore
{
public:
	glStore				();
	virtual ~glStore	();

	/**
	 * Adds a value in the store.
	 *
	 * @param _value the value to add
	 */
	void			add1			( const Type& _value );

	/**
	 * Adds a 2-tuple in the store.
	 *
	 * @param _sValue the first value to add (e.g., s texture coordinate)
	 * @param _tValue the second value to add (e.g., t texture coordinate)
	 */
	void			add2			( const Type& _sValue, const Type& _tValue );

	/**
	 * Adds a 2-tuple in the store.
	 *
	 * @param _xCoord the first value to add (e.g., position x-coordinate)
	 * @param _yCoord the second value to add (e.g., position y-coordinate)
	 * @param _zCoord the third value to add (e.g., position z-coordinate)
	 */
	void			add3			( const Type& _xCoord, const Type& _yCoord,
										const Type& _zCoord );

	/**
	 * Adds a 2-tuple in the store.
	 *
	 * @param _red the first value to add (e.g., red color component)
	 * @param _green the second value to add (e.g., green color component)
	 * @param _blue the third value to add (e.g., blue color component)
	 * @param _alpha the fourth value to add (e.g., alpha color component)
	 */
	void			add4			( const Type& _red, const Type& _green,
										const Type& _blue, const Type& _alpha );

	/**
	 * Returns the data in the store.
	 */
	const void*		getRawData		()	const	{ return &( m_store[ 0 ] ); }

	/**
	 * Returns the size of tuples contained in the store.
	 *
	 * @return the size of tuples
	 */
	unsigned int	getElementSize	()	const	{ return m_elementSize; }

	/**
	 * Sets the size of tuples contained in the store.
	 *
	 * @param _elementSize the new size of tuples
	 */
	void			setElementSize	( int _elementSize );

	/**
	 * Returns the number of tuples (depending on m_elementSize value) contained
	 * in the store. If interlacing is enabled, returns 0.
	 *
	 * @return
	 */
	unsigned int	getNbElements	()	const;

	/**
	 * Returns the size of the store.
	 *
	 * @return the size of the store
	 */
	unsigned int	size			()	const	{ return m_store.size(); }

	/**
	 * Returns the size of the store in bytes.
	 *
	 * @return the size of the store in bytes
	 */
	unsigned int	getRawSize	()	const	{ return m_store.size() * sizeof( Type ); }

	/**
	 * Requests that the capacity of the store be at least a given capacity.
	 *
	 * @param _capacity the requested capacity for the store
	 */
	void			reserve			( int _capacity );

	/**
	 * Requests that the size of the store be equal to a given size.
	 *
	 * @param _size the requested size for the store
	 * @param _object object whose content is copied to the added elements
	 */
	void			resize			( int _size, const Type& _object );

	/**
	 * Sets interlacing. If enabled, the store can contain interlaced vertex
	 * attributes.
	 *
	 * @see glVertexAttribPointer() "stride" parameter
	 * @param _interlacing a boolean to enable/disable interlacing
	 */
	void			setInterlacing	( bool _interlacing );

	/**
	 * Clears the content of the store.
	 */
	void			clear			();

	/**
	 * Prints the content of the store, for debug purpose only.
	 */
	void			printStore		();

private:
	/**
	 * The vector used to store elements.
	 */
	std::vector< Type >	m_store;

	/**
	 * The size of stored tuples.
	 *
	 * If -1, interlacing is enabled. If 0, interlacing is disabled and no addX
	 * function has been called. Else, the store contains m_elementSize tuples.
	 */
	int				m_elementSize;
};

#include "glStore.hpp"

#endif /* GLSTORE_H_ */
